/*
 * Copyright 2020-2025 the original author or authors.
 * You cannot use this file unless authorized by the author.
 */

package org.ipig.commons.helper;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.math.NumberUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * 数字处理
 *
 * @author <a href="mailto:comchnts@163.com">chinats</a>
 * @version $$Id: NumberHelper.java 15 2020-04-21 12:04:17Z ts <comchnts@163.com> $$
 * @since 1.0
 */
@Slf4j
public class NumberHelper extends NumberUtils {
    /**
     * 将输入两数字字符串转化成BigDecimal再相加
     * <li>如果输入的是非Number，则采用默认数字字符串</li>
     *
     * @param inNum1 输入数字字符串1
     * @param inNum2 输入数字字符串2
     * @return BigDecimal
     */
    public static BigDecimal add(String inNum1, String inNum2) {
        BigDecimal bigNum1 = createBigDecimal(inNum1, "0");
        BigDecimal bigNum2 = createBigDecimal(inNum2, "0");
        BigDecimal result = bigNum1.add(bigNum2);
        return result;
    }

    /**
     * 将输入两数字字符串转化成BigDecimal再相加
     * <li>如果输入的是非Number，则采用默认数字字符串</li>
     * <li>如果默认数字字符串是非Number,则默认0</li>
     *
     * @param inNum1  输入数字字符串1
     * @param defNum1 默认数字字符串1
     * @param inNum2  输入数字字符串2
     * @param defNum2 默认数字字符串2
     * @return BigDecimal
     */
    public static BigDecimal add(String inNum1, String defNum1, String inNum2, String defNum2) {
        BigDecimal bigNum1 = createBigDecimal(inNum1, defNum1);
        BigDecimal bigNum2 = createBigDecimal(inNum2, defNum2);
        BigDecimal result = bigNum1.add(bigNum2);
        return result;
    }

    /**
     * 将输入数字字符串转化成BigDecimal
     * <li>如果输入的是非Number，则采用默认数字字符串</li>
     * <li>如果默认数字字符串是非Number,则默认0</li>
     *
     * @param inNum  输入数字字符串[仅支持0~9加小数点]
     * @param defNum 默认数字字符串[仅支持0~9加小数点]
     * @return BigDecimal
     */
    public static BigDecimal createBigDecimal(String inNum, String defNum) {
        BigDecimal bigNum = null;
        if (NumberUtils.isNumber(inNum)) {
            bigNum = NumberUtils.createBigDecimal(inNum);
        } else {
            log.debug("方法转化非数字字符串【" + inNum + "】采用默认值【" + defNum + "】");
            if (NumberUtils.isNumber(defNum)) {
                bigNum = NumberUtils.createBigDecimal(defNum);
            } else {
                bigNum = NumberUtils.createBigDecimal("0");
            }
        }
        return bigNum;
    }

    /**
     * 将输入数字字符串转化成BigDecimal
     * <li>如果输入的是非Number，则采用默认0</li>
     *
     * @param inNum 输入数字字符串
     * @return BigDecimal
     */
    public static BigDecimal createBigDecimal(String inNum) {
        return createBigDecimal(inNum, "0");
    }

    /**
     * 将输入数字转化成BigDecimal
     *
     * @param inNum 输入数字字符串
     * @return BigDecimal
     */
    public static BigDecimal createBigDecimal(int inNum) {
        return new BigDecimal(inNum);
    }

    /**
     * 将输入数字转化成BigDecimal
     *
     * @param inNum 输入数字字符串
     * @return BigDecimal
     */
    public static BigDecimal createBigDecimal(long inNum) {
        return new BigDecimal(inNum);
    }

    /**
     * 将输入数字转化成BigDecimal
     *
     * @param inNum 输入数字字符串
     * @return BigDecimal
     */
    public static BigDecimal createBigDecimal(double inNum) {
        return new BigDecimal(inNum);
    }

    /**
     * 将输入数字字符串转化成BigDecimal再次方
     * <li>如果输入的是非Number，则采用默认0</li>
     *
     * @param inNum 输入数字字符串
     * @param n     次方  范围在0到999999999之间
     * @return BigDecimal
     */
    public static BigDecimal createBigDecimalPow(String inNum, int n) {
        return createBigDecimal(inNum, "0").pow(n);
    }

    /**
     * 将输入数字字符串转化成BigDecimal,
     * <li>如果输入的是非Number，则采用默认0</li>
     *
     * @param inNum        输入数字字符串
     * @param newScale     保留小数位数
     * @param roundingMode 舍入模式
     * @return BigDecimal
     */
    public static BigDecimal setScale(String inNum, int newScale, RoundingMode roundingMode) {
        return createBigDecimal(inNum, "0").setScale(newScale, roundingMode);
    }

    /**
     * 将输入数字字符串转化成BigDecimal
     * <li>如果输入的是非Number，则采用默认0</li>
     * <li>舍入模式默认采用 四舍五入RoundingMode.HALF_UP</li>
     *
     * @param inNum    输入数字字符串
     * @param newScale 保留小数位数
     * @return BigDecimal
     */
    public static BigDecimal setScale(String inNum, int newScale) {
        return setScale(inNum, newScale, RoundingMode.HALF_UP);
    }


    /**
     * 将输入BigDecimal保留指定的小数位数
     * <li>如果输入BigDecimal为null，则返回默认0的BigDecimal</li>
     *
     * @param inNum        输入BigDecimal
     * @param newScale     保留小数位数
     * @param roundingMode 舍入模式
     * @return BigDecimal
     */
    public static BigDecimal setScale(BigDecimal inNum, int newScale, RoundingMode roundingMode) {
        BigDecimal result = null;
        if (inNum != null) {
            result = inNum.setScale(newScale, roundingMode);
        } else {
            result = new BigDecimal("0");
        }
        return result;
    }

    /**
     * 将输入BigDecimal保留指定的小数位数
     * <li>如果输入BigDecimal为null，则返回默认0的BigDecimal</li>
     * <li>舍入模式默认采用 四舍五入RoundingMode.HALF_UP</li>
     *
     * @param inNum    输入BigDecimal
     * @param newScale 保留小数位数
     * @return BigDecimal
     */
    public static BigDecimal setScale(BigDecimal inNum, int newScale) {
        return setScale(inNum, newScale, RoundingMode.HALF_UP);
    }
}
